<?php

class Twis_Handler_Base
{
    private $_template = null;
    private $_request = null;
    private $_response = null;
    private $_proxy = null;
    private $_config = null;
    private $_router = null;
    private $_sessionKey = null;

    public function __construct($config = array())
    {
        if($config) {
            $this->getConfig()->add($config);
        }
        $this->init();
    }

    public function init()
    {
        // Do nothing.
    }

    public function setConfig($config)
    {
        $this->_config = $config;
    }

    public function getConfig()
    {
        if(empty($this->_config)) {
            $this->_config = new System_Config();
            System_Registry::set('config', $this->_config);
        }
        return $this->_config;
    }

    public function setTemplate($template)
    {
        $this->_template = $template;
    }

    public function getTemplate()
    {
        if(empty($this->_template)) {
            $this->_template = new Twis_Template($this->getConfig());
            $this->_template->setProxy($this->getProxy());
            $this->_template->setUrl($this->getUrl());
        }
        return $this->_template;
    }

    public function getRequest()
    {
        if(empty($this->_request)) {
            $this->_request = System_Http_Request::getInstance();
        }
        return $this->_request;
    }

    public function getResponse()
    {
        if(empty($this->_response)) {
            $this->_response = System_Http_Response::getInstance();
        }
        return $this->_response;
    }

    public function setProxy($proxy)
    {
        $this->_proxy = $proxy;
    }

    public function getProxy()
    {
        if(empty($this->_proxy)) {
            $apiType = $this->getConfig()->get('api.type', 'local');
            $apiTypes = array('local', 'xmlrpc', 'jsonrpc', 'soap');
            if(!in_array($apiType, $apiTypes)) {
                throw new Exception('Not supported api type');
            }
            $apiMap = $this->getConfig()->get('api.map');
            $this->_proxy = new System_Api_Local($apiMap);
        }
        return $this->_proxy;
    }

    public function getUrl()
    {
        if(empty($this->_url)) {
            $baseUrl = $this->getRequest()->getBaseUrl();
            $rewriteUrls = $this->getConfig()->get('url.rewrite', false);
            $this->_url = new System_Url($baseUrl, $rewriteUrls);
        }
        return $this->_url;
    }

    public function setRouter($router)
    {
        $this->_router = $router;
    }

    public function getRouter()
    {
        if(empty($this->_router)) {
            $defaultRouter = $this->getConfig()->get('url.index', 'index');
            $this->_router = trim($this->getRequest()->getQuery('router', $defaultRouter), '/');
        }
        return $this->_router;
    }

    public function setSessionKey($sessionKey, $remember = false)
    {
        $this->_sessionKey = $sessionKey;
        $config = $this->getConfig();
        $expire = null;
        if ($remember) {
            $expire = time() + $config->get('cookie.expire', 3600 * 24 * 30);
        }

        $path = $config->get('cookie.path', '/');
        $domain = $config->get('cookie.domain', null);
        $sessionPrefix = $config->get('cookie.prefix', '');
        $sessionName = $sessionPrefix . 'session_key';
        $this->getResponse()->setCookie($sessionName, $sessionKey, $expire, $path, $domain);
    }

    public function removeSessionKey()
    {
        $this->_sessionKey = null;
        $config = $this->getConfig();
        $path = $config->get('cookie.path', '/');
        $domain = $config->get('cookie.domain', null);
        $sessionPrefix = $config->get('cookie.prefix', '');
        $sessionName = $sessionPrefix . 'session_key';
        $this->getResponse()->removeCookie($sessionName, $path, $domain);
    }

    public function getSessionKey()
    {
        if(empty($this->_sessionKey)) {
            $sessionPrefix = $this->getConfig()->get('cookie.prefix', '');
            $sessionName = $sessionPrefix . 'session_key';
            $this->_sessionKey = $this->getRequest()->getCookie($sessionName);
        }
        return $this->_sessionKey;
    }

}
